﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebCrawler.Model;
using WebCrawler.Service;

namespace WebCrawler.ViewModel
{
    public class Web720yunViewModel : ViewModelBase
    {
        public Web720yunViewModel()
        {
            initBaseData();

            Messenger.Default.Register<string>(this, "StepMessage", receiveStepMessage);
        }

        #region 属性
        private Web720yunModel _web720yun;
        public Web720yunModel Web720yun
        {
            get
            {
                if (_web720yun == null)
                    _web720yun = new Web720yunModel();
                return _web720yun;
            }
            set { _web720yun = value; RaisePropertyChanged(() => Web720yun); }
        }

        private string _stepMessage;
        public string StepMessage
        {
            get { return _stepMessage; }
            set { _stepMessage = value; RaisePropertyChanged(() => StepMessage); }
        }

        public bool IsDownloading
        {
            get { return _isDownloading; }
            set { _isDownloading = value; RaisePropertyChanged(() => IsDownloading); }
        }
        private bool _isDownloading = false;
        #endregion

        #region 命令
        public RelayCommand StartDownloadCmd
        {
            get
            {
                if (_startDownloadCmd == null)
                    _startDownloadCmd = new RelayCommand(startDownload, canStartDownload);
                return _startDownloadCmd;
            }
            set { _startDownloadCmd = value; }
        }
        public RelayCommand _startDownloadCmd;
        #endregion

        #region 辅助函数

        private void initBaseData()
        {
            Web720yun.DownloadSingleImage = false;
            Web720yun.Tile = 4;

            Web720yun.PlaceholderList = new List<ComplexInfoModel>() {
              new ComplexInfoModel(){ Key="1",Text="0" },
              new ComplexInfoModel(){ Key="2",Text="00" },
              new ComplexInfoModel(){ Key="3",Text="000" }
            };
            Web720yun.Placeholder = Web720yun.PlaceholderList[0];

            Web720yun.ImageQualityList = new List<ComplexInfoModel>() {
              new ComplexInfoModel(){ Key="1",Text="l1" },
              new ComplexInfoModel(){ Key="2",Text="l2" },
              new ComplexInfoModel(){ Key="3",Text="l3" },
              new ComplexInfoModel(){ Key="4",Text="l4" },
              new ComplexInfoModel(){ Key="5",Text="l5" }
            };
            Web720yun.ImageQuality = Web720yun.ImageQualityList[2];

            // 测试
            Web720yun.Url = "https://ssl-panoimg104.720static.com/resource/prod/bbd3fc38s1m/728jOdem5y3/21181833/imgs";
            Web720yun.Placeholder = Web720yun.PlaceholderList[1];
            Web720yun.Tile = 7;
            Web720yun.Name = "井冈山";
        }

        private async void startDownload()
        {
            //string folderPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Desktop)}/{Web720yun.Name}";
            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}/{Web720yun.Name}";

            StepMessage = "开始";
            IsDownloading = true;

            await download(Web720yun.Url, Web720yun.ImageQuality.Text, Web720yun.Tile, Web720yun.Placeholder.Text, folderPath, Web720yun.DownloadSingleImage);

            IsDownloading = false;
            StepMessage = "完成";
        }

        private bool canStartDownload()
        {
            return true;
        }

        private void receiveStepMessage(string message)
        {
            StepMessage = message;
        }

        private async Task download(string url, string quality, int tile, string placeholder, string folder, bool saveSingleImage)
        {
            string curTile = string.Empty;
            string curUrl = string.Empty;

            // 左上
            curTile = 1.ToString(placeholder);
            curUrl = $"{url}/f/{quality}/{curTile}/{quality}_f_{curTile}_{curTile}.jpg";
            Messenger.Default.Send($"计算左上角像素", "StepMessage");
            Mat upperLeft = await ImageUtility.DownloadImageAsync(curUrl, "", false);

            // 右下
            curTile = tile.ToString(placeholder);
            curUrl = $"{url}/f/{quality}/{curTile}/{quality}_f_{curTile}_{curTile}.jpg";
            Messenger.Default.Send($"计算右下角像素", "StepMessage");
            Mat lowerRight = await ImageUtility.DownloadImageAsync(curUrl, "", false);

            Dictionary<string, Mat> mats = new Dictionary<string, Mat>();
            // 请求单张图片
            for (int i = 0; i < 6; i++)
            {
                string side = string.Empty;
                switch (i)
                {
                    case 0: side = "f"; break;
                    case 1: side = "b"; break;
                    case 2: side = "r"; break;
                    case 3: side = "l"; break;
                    case 4: side = "u"; break;
                    case 5: side = "d"; break;
                }

                Mat[,] matpArray = new Mat[tile, tile];

                for (int j = 0; j < tile; j++)
                {
                    for (int k = 0; k < tile; k++)
                    {
                        string row = (j + 1).ToString(placeholder);
                        string col = (k + 1).ToString(placeholder);

                        curUrl = $"{url}/{side}/{quality}/{row}/{quality}_{side}_{row}_{col}.jpg";
                        string fileName = $"{folder}/single/{quality}_{side}_{row}_{col}.jpg";

                        Messenger.Default.Send($"下载：{curUrl}", "StepMessage");
                        Mat mat = await ImageUtility.DownloadImageAsync(curUrl, fileName, saveSingleImage);

                        matpArray[j, k] = mat;
                    }
                }

                Messenger.Default.Send($"合并：{side}", "StepMessage");
                Mat mat_Side = await ImageUtility.MergeSide(side, folder, matpArray, upperLeft.Size(), lowerRight.Size());
                mats[side] = mat_Side;
            }

            // 释放
            upperLeft.Dispose();
            lowerRight.Dispose();

            // 合并Cube
            Messenger.Default.Send($"合并：Cubemap", "StepMessage");
            Mat cubemap = await ImageUtility.MergeCubemapAsync(folder, mats);

            // 转换全景图
            Messenger.Default.Send($"合并：Panorama", "StepMessage");
            await ImageUtility.CubemapToPanoramaAsync(folder, cubemap);
        }
        #endregion

        public void ReleaseRegister()
        {
            Messenger.Default.Unregister(this);
        }
    }
}